package com.xctech.iot.mqtt.sdk.subscribe;

import com.xctech.iot.mqtt.sdk.core.MqttAbstractClient;
import com.xctech.iot.mqtt.sdk.subscribe.message.MqttFunctionMessageListener;
import com.xctech.iot.mqtt.sdk.subscribe.message.MqttPropertySetMessageListener;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

/**
 * <pre>
 * mqtt 消费端
 * </pre>
 *
 * @author: feihu.liang
 * @since: 2024/4/11 14:15
 */
@Slf4j
@Component
public class MqttClientListener extends MqttAbstractClient {

    private MqttClient client;

    private static final String EVENT_POST_REPLY_TOPIC = "/sys/{0}/{1}/thing/event/+/post_reply";
    private static final String SERVICE_DOWN_TOPIC = "/sys/{0}/{1}/thing/service/+";
    private static final String PROPERTY_SET_TOPIC = "/sys/{0}/{1}/thing/service/property/set";


    /**
     * <pre>
     * 建立连接
     * </pre>
     *
     * @param
     * @return void
     */
    @Override
    public void connect() throws MqttException {
        client = new MqttClient(mqttConfig.getHostUrl(),
                mqttConfig.getClientId() + "_consumer_" + System.currentTimeMillis(), new MemoryPersistence());
        // 建立连接
        client.connect(getConnOptions());
        log.info("mqtt consumer client connect success");

        // 订阅监听
        String propertySetTopic = MessageFormat.format(PROPERTY_SET_TOPIC, mqttConfig.getProductId(), mqttConfig.getDeviceId());
        client.subscribe(propertySetTopic, new MqttPropertySetMessageListener());
        String serviceDownTopic = MessageFormat.format(SERVICE_DOWN_TOPIC, mqttConfig.getProductId(), mqttConfig.getDeviceId());
        client.subscribe(serviceDownTopic, new MqttFunctionMessageListener());
    }


    /**
     * <pre>
     * 是否连接
     * </pre>
     *
     * @param
     * @return java.lang.Boolean
     */
    public Boolean isConnected() {
        return client != null && client.isConnected();
    }

}
